/*
The surface-physics project: http://code.google.com/p/surface-physics/
Adds real world physics based on the Bullet physics engine, to bases in the Orbiter space
flight simulation software.

Written by Abhijit Nandy
License : Apache License 2.0

Bump_Queue.cpp

This file implements a common class for a pointer that can  point at different type of objects.
Also contains the world transform m[16] that is a common member to both objects types
and thus can be factored out, into this class.

*/


/* Class declaration */
#include "Bump_Queue.h"




/**
 * Constructor for the class. Allocates the object array.
 */
template<class T>
Bump_Queue<T>::Bump_Queue(int capacity)
{
	if(capacity > 0){  //can hold 1 or more elements, so minimum size = 1
		this->capacity = capacity;
		size = 0; //current size
		objArray = (T*)new(T[capacity]);
		if(objArray){
			front = 1;
			rear = 0;
		}

		delete[] objArray;
	}

}


/**
 * Destructor, frees the object array and NULLs it, resets size, capacity to 0
 */
template<class T>
Bump_Queue<T>::~Bump_Queue()
{
	if(objArray){
		//free the queue object array
		delete[] objArray;
		objArray = NULL;
		size = 0;
		capacity = 0;
	}

}


/**
 * Is the queue empty ?
 */
template<class T>
bool Bump_Queue<T>::isEmpty()
{
	if(size == 0)
		return true;

	return false;

}

/**
 * Make the queue empty, doesnt NULL the pointers, only resets the indices
 */
template<class T>
int Bump_Queue<T>::makeEmpty()
{
	front = 0;
	rear = 0;
	size = 0;
}


/**
 * Enqueue an object pointer at the rear, will not enqueue NULL pointers
 */
template<class T>
int Bump_Queue<T>::enqueue(T* pObj)
{
	if(pObj && size < capacity){	//size is kept in sync
		objArray[rear] = pObj;
		rear = (rear + 1)%(capacity);
		size++;
		return 1;
	}

	return 0;
}


/**
 * Dequeue an object pointer from the front
 */
template<class T>
T* Bump_Queue<T>::dequeue()
{
	T* pObj;

	if(!isEmpty()){
		//printf("%d\n", front);
		pObj = objArray[front];
		front = (front + 1)%(capacity);
		size--;
		return pObj;
	}

	return NULL;
}


/**
 * Check the object at the front currently without dequeuing
 */
template<class T>
T* Bump_Queue<T>::peekFront()
{
	if(isEmpty())
		return objArray[front];

	return NULL;
}


/**
 * Prints the queue, assumes a printable member 'int id' in class T
 *
 */
template<class T>
void Bump_Queue<T>::printQueue()
{
	int i;
	for(i=0; i<capacity; i++){
		printf("Q[%2d] = %d", i, objArray[i]->id);

		if(i == front)
			printf("<-f\n");
		else if(i == rear)
			printf("<-r\n");
		else
			printf("\n");
	}
}

